home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / editors / mutt / me2s_pl7.zoo / mu_edit2 / mc2 / supp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  14.0 KB  |  550 lines

  1. /* 
  2.  * supp.c : support routines for the Mutt compiler
  3.  *     label routines
  4.  *    pgms
  5.  *     vars
  6.  */
  7.  
  8. /* Copyright 1990, 1991, 1992 Craig Durland
  9.  *   Distributed under the terms of the GNU General Public License.
  10.  *   Distributed "as is", without warranties of any kind, but comments,
  11.  *     suggestions and bug reports are welcome.
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <os.h>
  16. #include <dtable.h>
  17. #include "mm.h"
  18. #include "mc.h"
  19.  
  20. extern address pcaddr();
  21. extern char
  22.   ebuf[],
  23.   *savestr(), *strcpy(), *spoof();
  24. extern FILE *lstfile;    /* in mc.c */
  25.  
  26. MMDatum *getconst();
  27.  
  28. /* ******************************************************************** */
  29. /* ****************** error routines ********************************** */
  30. /* ******************************************************************** */
  31.  
  32. extern char *muttfile;            /* in mc.c */
  33. extern int srcline, errors, warnings;    /* in mc.c */
  34.  
  35. void errmsg(errtype,msg) char *errtype, *msg;
  36. {
  37.   char buf[300];
  38.  
  39.   spoof(buf,"%s %d %s: %s\n",muttfile,srcline,errtype,msg);
  40.   if (lstfile) fputs(buf,lstfile);
  41.   fputs(buf,stdout);
  42. }
  43.  
  44. int no_warn = FALSE, no_gripe = FALSE;
  45.  
  46. void gripe(msg) char *msg; { if (!no_gripe) errmsg("Note",msg); }
  47. void groan(msg) char *msg;
  48. {
  49.   warnings++; if (!no_warn) errmsg("Warning",msg);
  50. }
  51. void moan(msg)  char *msg; { errors++;   errmsg("Error",msg); }
  52. void bitch(msg) char *msg; { moan(msg);  exit(1); }
  53.  
  54.     /* Internal error : print message and bail out */
  55. bail(msg) char *msg;
  56. {
  57.   fprintf(stderr,"Internal error!  %s\n",msg);
  58.   exit(1);
  59. }
  60.  
  61. /* ******************************************************************** */
  62. /* ******************************* misc ******************************* */
  63. /* ******************************************************************** */
  64.  
  65. is_object_type(type)
  66. {
  67.   return (type == LIST || type == STRING);
  68. }
  69.  
  70. /* ******************************************************************** */
  71. /* ****************** label routines ********************************** */
  72. /* ******************************************************************** */
  73.  
  74. static declare_and_init_dTable(label_table, address);
  75.  
  76. genlabel()
  77. {
  78.   static int labels = 0;
  79.  
  80.   if (!xpand_dTable(&label_table, 1, 100,100))
  81.     bail("Out of memory! Can't expand label table.");
  82.   
  83.   label_table.table[labels] = NIL;
  84.   return labels++;
  85. }
  86.  
  87. address getlabel(label) { return label_table.table[label]; }
  88.  
  89. void stufflabel(label)
  90. {
  91.   if (lstfile) fprintf(lstfile,"%4u: L%d:\n",pcaddr(),label);
  92.   label_table.table[label] = pcaddr();
  93. }
  94.  
  95. typedef struct { int name; int label; } NamedLabel;
  96.  
  97. static declare_and_init_dTable(named_label_table,NamedLabel);
  98. static declare_and_init_dTable(lname_heap,char);
  99. static int named_labels = 0, lptr = 0;
  100.  
  101. gen_named_label(name) char *name;
  102. {
  103.   int n;
  104.  
  105.   if (get_named_label(name) != -1)
  106.   {
  107.     moan(spoof(ebuf,"Label \"%s\" already in use.",name));
  108.     return 0;
  109.   }
  110.  
  111.   if (!xpand_dTable(&named_label_table, 1, 10,10))
  112.     bail("Out of memory! Can't expand named label table.");
  113.  
  114.   n = strlen(name) +1;
  115.   if (!xpand_dTable(&lname_heap, n, 256,256))
  116.     bail("Out of memory! Can't expand named label heap.");
  117.  
  118.   named_label_table.table[named_labels].name = lptr;
  119.   strcpy(&lname_heap.table[lptr], name); lptr += n;
  120.   return (named_label_table.table[named_labels++].label = genlabel());
  121. }
  122.  
  123. get_named_label(name) char *name;    /* return label */
  124. {
  125.   char *heap_start = lname_heap.table;
  126.   int j;
  127.   NamedLabel *label = named_label_table.table;
  128.  
  129.   for (j = named_labels; j--; label++)
  130.     if (0 == strcmp(name, heap_start + label->name)) return label->label;
  131.  
  132.   return -1;
  133. }
  134.  
  135. void reset_named_labels()
  136. {
  137.   char *heap_start = lname_heap.table;
  138.   int j;
  139.   NamedLabel *label = named_label_table.table;
  140.  
  141.   for (j = named_labels; j--; label++)
  142.     if (getlabel(label->label) == NIL)
  143.       moan(spoof(ebuf,"Label \"%s\" unresolved.", heap_start + label->name));
  144.  
  145.   reset_dTable(&lname_heap);
  146.   reset_dTable(&named_label_table);
  147.   named_labels = lptr = 0;
  148. }
  149.  
  150. /* ******************************************************************** */
  151. /* ****************** PGMs ******************************************** */
  152. /* ******************************************************************** */
  153.  
  154. typedef struct { char *name; address addr; uint8 flags; } PgmTable;
  155.  
  156. static int pgmn = 0;
  157. static declare_and_init_dTable(pgm_table, PgmTable);
  158.  
  159. /* ??? use bsearch */
  160. address getpgm(name) char *name;
  161. {
  162.   register int j, lower = 0, upper = pgmn-1, x;
  163.   PgmTable *pgmtable = pgm_table.table;
  164.  
  165.   while (lower <= upper)
  166.   {
  167.     j = (lower+upper)/2;
  168.     if ((x = strcmp(name,pgmtable[j].name)) > 0) lower = j +1;
  169.     else
  170.       if (x < 0) upper = j -1;
  171.       else    /* found it */
  172.       {
  173.     if (pgmtable[j].flags & LEAR)
  174.       moan(spoof(ebuf,"%s is special and can't be used.",pgmtable[j].name));
  175.     return pgmtable[j].addr;
  176.       }
  177.   }
  178.   return NIL;
  179. }
  180.  
  181. addpgm(name) char *name;
  182. {
  183.   int i,j,x, flags = 0;
  184.   PgmTable *pgmtable;
  185.  
  186.   if (getvar(name) != -1) moan(spoof(ebuf,"\"%s\" is a var name.",name));
  187.  
  188.   if (!xpand_dTable(&pgm_table, 1, 50,20))
  189.     bail("Out of memory! Can't expand pgm table.");
  190.  
  191.   pgmtable = pgm_table.table;
  192.  
  193.   if (0 == strcmp(name,"MAIN")) flags = (MAIN | HIDDEN | LEAR);
  194.   for (i = 0; i < pgmn; i++)
  195.   {
  196.     if ((x = strcmp(pgmtable[i].name,name)) == 0)
  197.     {
  198.       if ((flags & LEAR) == 0)
  199.     bitch(spoof(ebuf,"pgm \"%s\" already used.",name));
  200.     }
  201.     else if (x > 0) break;
  202.   }
  203.  
  204.   for (j = pgmn; j > i; j--) pgmtable[j] = pgmtable[j-1];
  205.   if (!(pgmtable[i].name = savestr(name))) bail("Can't save pgm name");
  206.   pgmtable[i].addr = pcaddr(); pgmtable[i].flags = flags;
  207.   pgmn++;
  208.  
  209.   return i;
  210. }
  211.  
  212. pgms() { return pgmn; }
  213. void modpgm(n,f)   { pgm_table.table[n].flags |= f; }
  214.  
  215. address pgmaddr(n) { return      pgm_table.table[n].addr;  }
  216. char *pgmname(n)   { return      pgm_table.table[n].name;  }
  217. pgmflags(n)       { return (int)pgm_table.table[n].flags; }
  218.  
  219.     /* Return the id of the next pgm with id >= n, -1 if none */
  220. get_main(n)
  221. {
  222.   for (; n < pgmn; n++) if (pgm_table.table[n].flags & MAIN) return n;
  223.   return -1;
  224. }
  225.  
  226. /* ******************************************************************** */
  227. /* ****************** VARs ******************************************** */
  228. /* ******************************************************************** */
  229.  
  230. typedef struct
  231. {
  232.   int name;    /* offset into var_name_table */
  233.   unsigned int type;
  234.   int offset;    /* from var base (first var of same scope) */
  235.   uint8 scope;    /* LOCAL or GLOBAL */
  236.   int blobs;    /* number of VBlobs that make up blob */
  237.   int list;    /* index into blob array */
  238. } Var;
  239.  
  240. static int
  241.   vars = 0, blobs = 0,
  242.   local_objects = 0,
  243.   global_objects = 0,
  244.   global_vars = 0,    /* number of global vars and where local vars start */
  245.   vnbase = 0,        /* ditto but for var names */
  246.   size_of_global_vars = 0,
  247.   size_of_local_vars = 0,
  248.   global_blobs = 0;   /* number of global blobs and where local blobs start */
  249. VBlob *proto_name();
  250.  
  251. static declare_and_init_dTable(var_table,  Var);
  252. static declare_and_init_dTable(blob_table, VBlob);
  253.  
  254.     /* ************ Var Names ************************ */
  255. static declare_and_init_dTable(var_name_table, char);
  256. static int vptr = 0;
  257.  
  258.     /* WARNING!!!
  259.      *   The proto stuff uses a pointer into the var_name_table.table.  This
  260.      *     is a no-no since the table can be realloc()ed and thus move.  I
  261.      *     need to fix this.  But since this bug has been here forever and
  262.      *     I've never hit it, I'm going to punt for now.
  263.      */
  264. static int add_var_name(name) char *name;
  265. {
  266.   int len = strlen(name) +1, start = vptr;
  267.  
  268.   if (!xpand_dTable(&var_name_table, len, 1024,512))
  269.     bail("Out of memory! Can't expand var name table.");
  270.   strcpy(&var_name_table.table[vptr],name);
  271.   vptr += len;
  272.  
  273.   return start;
  274. }
  275.  
  276. #define GET_VAR_NAME(n) &var_name_table.table[n]
  277.  
  278.  
  279. void reset_vars()    /* reset var tables for new function */
  280. {
  281.   vars = global_vars; size_of_local_vars = 0;
  282.  
  283.   vptr = vnbase;
  284.   sizeof_dTable(&var_name_table) = vnbase;
  285.  
  286.   blobs = global_blobs;
  287.   local_objects = 0;
  288. }
  289.  
  290. addvar(name,type,var_size,scope) char *name; unsigned int type;
  291. {
  292.   int n, is_object;
  293.   Var *the_var;
  294.  
  295.   if (scope == GLOBAL && (getconst(name) || getpgm(name) ))
  296.     moan(spoof(ebuf,
  297.       "\"%s\" is a pgm or const - can't be reused as a var.",name));
  298.   if ((scope == LOCAL && proto_name(name)) ||
  299.       ((n = getvar(name)) != -1 && scope == vscope(n)))
  300.     bitch(spoof(ebuf,"var \"%s\" already in use.",name));
  301.  
  302.   is_object = is_object_type(type);
  303.  
  304.   if (!xpand_dTable(&var_table, 1, 30,10))
  305.     bail("Out of memory! Can't expand var table.");
  306.  
  307.   the_var = &var_table.table[vars];
  308.  
  309.   the_var->name = add_var_name(name);
  310.  
  311.   if (scope == LOCAL)
  312.   {
  313.     if (is_object) the_var->offset = local_objects++;
  314.     else
  315.     {
  316.       the_var->offset = size_of_local_vars;
  317.       size_of_local_vars += var_size;
  318.     }
  319.   }
  320.   else
  321.   {
  322.     global_vars++; vnbase = vptr;
  323.     if (is_object) the_var->offset = global_objects++;
  324.     else
  325.     {
  326.       the_var->offset = size_of_global_vars;
  327.       size_of_global_vars += var_size;
  328.     }
  329.   }
  330.   the_var->type  = type;
  331.   the_var->scope = scope;
  332.  
  333.   return vars++;    /* pass back the var id */
  334. }
  335.  
  336. static void blubber()
  337. {
  338.   if (!xpand_dTable(&blob_table, 1, 20,10))
  339.     bail("Out of memory! Can't expand blob table.");
  340. }
  341.  
  342. add_array(name,type,size,scope,dims,dim)
  343.   char *name; unsigned int type; int dim[];
  344. {
  345.   int j,n;
  346.  
  347.   blubber();
  348.   n = addvar(name,ARRAY,size,scope);
  349.   var_table.table[n].list = blobs;
  350.   blob_table.table[blobs].type = type;
  351.   blob_table.table[blobs].dims = dims;
  352.   for (j = 0; j < dims; j++) blob_table.table[blobs].dim[j] = dim[j];
  353.  
  354.   if (scope == GLOBAL) global_blobs++;
  355.  
  356.   blobs++;
  357.  
  358.   return n;
  359. }
  360.  
  361. #if 0        /* not used (yet) */
  362. add_vblob(name,offset,type,dims,dim) char *name; unsigned int type; int dim[];
  363. {
  364.   int j, n;
  365.  
  366.   blubber();
  367.   n = blobs++;
  368.   if (NULL == (blob_table.table[n].name = savestr(name)))
  369.     bail("Can't malloc vblob name.");
  370.  
  371.   blob_table.table[n].offset = offset;
  372.   blob_table.table[n].type = type; 
  373.   blob_table.table[n].dims = dims;
  374.   for (j = 0; j < dims; j++) blob_table.table[n].dim[j] = dim[j]; 
  375.  
  376.   return n;
  377. }
  378. #endif
  379.  
  380. vscope(n)      { return (int)var_table.table[n].scope; }
  381. char *vname(n) { return GET_VAR_NAME(var_table.table[n].name); }
  382. voffset(n)     { return var_table.table[n].offset; }
  383.  
  384. getvar(name) char *name;
  385. {
  386.   int i;
  387.  
  388.   for (i = global_vars; i < vars; i++)    /* first check local vars */
  389.     if (0 == strcmp(vname(i),name)) return i;
  390.  
  391.   for (i = 0; i < global_vars; i++)    /* then check globals */
  392.     if (0 == strcmp(vname(i),name)) return i;
  393.  
  394.   return -1;
  395. }
  396.  
  397. VBlob *get_blob(n) { return &blob_table.table[var_table.table[n].list]; }
  398.  
  399. typesize(type) unsigned int type;
  400. {
  401.   if ((type & POINTER) || type == BLOB) return sizeof(int32);
  402.   switch(type)
  403.   {
  404.     case INT8: case BOOLEAN: case STRING: return sizeof(uint8);
  405.     case INT16: return sizeof(int16);
  406.     case INT32: return sizeof(int32);
  407.     case FCNPTR: moan("typesize(FCNPTR)"); return 4;
  408.   }
  409.   /* NOTREACHED */
  410. }
  411. unsigned int mmtype(type) unsigned int type;
  412. {
  413. /*if (type & MCTYPE) bitch(spoof(ebuf,"mmtype(%d): not a MMable type.",type));*/
  414.   if (type & POINTER) return BLOB;
  415.   switch (type)
  416.   {
  417.     case INT8: case INT16: case INT32: return NUMBER;
  418.   }
  419.   return type;
  420. }
  421.  
  422. unsigned int vtype(n) { return (unsigned int)var_table.table[n].type; }
  423. unsigned int vctype(n) unsigned int n; { return mmtype(vtype(n)); }
  424.  
  425.     /* space needed to hold local vars */
  426. lvspace() { return size_of_local_vars; }
  427.     /* Number of local vars for current defun */
  428. lvars()   { return (vars -global_vars); }
  429. first_local_var() { return global_vars; }
  430.  
  431.  
  432. num_global_vars() { return global_vars; }    /* number of global vars */
  433.     /* space needed to hold global vars */
  434. gvspace() { return size_of_global_vars; }
  435. num_global_objects() { return global_objects; }
  436.  
  437.     /* Return the id of the next globabl variable with id >= n, -1 if
  438.      *   none.
  439.      */
  440. get_global_object(n)
  441. {
  442.   for (; n < global_vars; n++)
  443.     if (is_object_type(vtype(n))) return n;
  444.  
  445.   return -1;
  446. }
  447.  
  448. /* ******************************************************************** */
  449. /* ****************** Prototypes ************************************** */
  450. /* ******************************************************************** */
  451.  
  452. typedef struct
  453. {
  454.   char *name;
  455.   int blobs;    /* number of VBlobs that make up proto */
  456.   int list;    /* index into blob array */
  457. } Proto;
  458.  
  459. static Proto proto;
  460.  
  461. VBlob *proto_name(name) char *name;
  462. {
  463.   int n = proto.blobs;
  464.   VBlob *blob = &blob_table.table[proto.list];
  465.  
  466.   for (; n--; blob++)
  467.     if (0 == strcmp(blob->name,name)) return blob;
  468.  
  469.   return NULL;
  470. }
  471.  
  472. addproto(name) char *name;
  473. {
  474.   proto.name = NULL;
  475.   proto.blobs = proto.list = 0;
  476.   return 0;
  477. }
  478.  
  479. void killproto() { proto.blobs = 0; }
  480.  
  481. void moreproto(name,ntharg,type,dims,dim)
  482.   char *name; unsigned int type; int dim[];
  483. {
  484.   int j, n;
  485.  
  486.   if (proto_name(name)) moan(spoof(ebuf,"arg \"%s\" already in use.",name));
  487.   blubber();
  488.  
  489.   n = blobs++;
  490.   j = add_var_name(name);    /* HP-UX s800 7.0 CC bug */
  491.   blob_table.table[n].name   = GET_VAR_NAME(j);
  492.   blob_table.table[n].offset = ntharg;
  493.   blob_table.table[n].type   = type; 
  494.   blob_table.table[n].dims   = dims;
  495.   for (j = 0; j < dims; j++) blob_table.table[n].dim[j] = dim[j]; 
  496.  
  497.   if (proto.blobs == 0) proto.list = n;
  498.   proto.blobs++;
  499. }
  500.  
  501. #if 0        /* not used (yet) */
  502. VBlob *proto_arg(nth_arg)
  503. {
  504.   int n = proto.blobs;
  505.   VBlob *blob = &blob_table.table[proto.list];
  506.  
  507.   for (; n--; blob++)
  508.     if (blob->offset == nth_arg) return blob;
  509.  
  510.   return NULL;
  511. }
  512. #endif
  513.  
  514. /* ******************************************************************** */
  515. /* ************************ CONSTS ************************************ */
  516. /* ******************************************************************** */
  517.  
  518. /* Here is where I save (const foo <value>) */
  519.  
  520. typedef struct { char *name; MMDatum rv; } Const;
  521.  
  522. static int nconsts = 0;
  523.  
  524. static declare_and_init_dTable(consts, Const);
  525.  
  526. MMDatum *getconst(name) char *name;
  527. {
  528.   Const *ptr;
  529.   int j;
  530.  
  531.   for (j = nconsts, ptr = consts.table; j--; ptr++)
  532.     if (strcmp(name,ptr->name) == 0) return &ptr->rv;
  533.  
  534.   return NULL;
  535. }
  536.  
  537. void add_const(name,rv) char *name; MMDatum *rv;
  538. {
  539.   if (getconst(name) || proto_name(name) || getvar(name) != -1)
  540.     { moan(spoof(ebuf,"\"%s\" already defined.",name)); return; }
  541.  
  542.   if (!xpand_dTable(&consts, 1, 10,10))
  543.     bail("Out of memory! Can't expand constant table.");
  544.  
  545.   consts.table[nconsts].name = savestr(name);
  546.   consts.table[nconsts].rv = *rv;
  547.  
  548.   nconsts++;
  549. }
  550.